import hashlib
import uuid
import time
import requests
import json
import redis
from numpy.compat import basestring

from Util.request_token_util import upm_token_server


class UpmToken:
    def __init__(self, token=None, usid=None):
        self.token = token
        self.usid = usid

    def get_token(self):
        return self.token

    def set_token(self, token):
        self.token = token

    def get_usid(self):
        return self.usid

    def set_usid(self, usid):
        self.usid = usid

    def get_head_map(self):
        return {
            "X-Token": self.token
        }

    def get_cookie_map(self):
        return {
            "usid": self.usid,
            "X-Token": self.token
        }


class UpmTokenServer:

    def __init__(self, app_id, app_secret, login_id, password, get_token_url, verify_token_url, redis_key,
                 redis_host='localhost', redis_port=6379, redis_db=5, redis_password=""):
        self.app_id = app_id
        self.app_secret = app_secret
        self.login_id = login_id
        self.password = password
        self.get_token_url = get_token_url
        self.verify_token_url = verify_token_url
        self.redis_key = redis_key
        self.redis_client = redis.Redis(host=redis_host, port=redis_port, db=redis_db, password=redis_password)

    def sha(self, str_text, str_type):
        # 返回值
        str_result = None
        # 检查输入字符串
        if str_text and isinstance(str_text, basestring):
            try:
                # 创建一个加密对象，并传入加密类型
                sha = hashlib.new(str_type)
                # 传入要加密的字符串（确保是字节类型）
                sha.update(str_text.encode('utf-8'))
                # 得到字节类型结果
                byte_buffer = sha.digest()

                # 将字节转换为16进制字符串
                str_hex_string = byte_buffer.encode('hex')

                # 得到返回结果
                str_result = str_hex_string
            except ValueError as e:
                # 如果加密类型不支持，抛出异常
                print("Unsupported hashing type: {}".format(str_type))
                # 可以选择抛出异常或返回None

        return str_result

    def verify_token(self):
        # 获取缓存中的token
        upm_token = self.get_redis_token()
        if not upm_token:
            print("Token获取失败")
            return False

        # 设置请求头
        headers = upm_token.get_head_map()
        # 设置cookie
        cookies = upm_token.get_cookie_map()
        print("verify_token request headers: {}".format(headers))
        print("verify_token request cookies: {}".format(cookies))
        response = requests.get(self.verify_token_url, headers=headers, cookies=cookies, proxies={})
        data = response.json()

        if data.get('status').get('code') == "E34001":
            token = self.get_token()
            return bool(token)
        return True

    def get_redis_token(self):
        token = self.redis_client.get(self.redis_key)
        if not token:
            token_str = self.get_token()
            return UpmToken(**json.loads(token_str))
        else:
            return UpmToken(**json.loads(token))

    def get_token(self):
        data = {
            "loginId": self.login_id,
            "password": self.password
        }
        timestamp = int(time.time() * 1000)  # 毫秒级时间戳
        randomStr = str(uuid.uuid4())
        # 计算token
        token = self.sha(
            "appSecret={}&randomStr={}&timestamp={}".format(self.app_secret, randomStr, timestamp), "sha512")

        headers = {
            'timestamp': str(timestamp),
            'randomStr': randomStr,
            'appId': self.app_id,
            'token': token
        }

        response = requests.post(self.get_token_url, headers=headers, json=data, proxies={})
        response_data = response.json().get("data")

        self.redis_client.set(self.redis_key, json.dumps(response_data))
        return json.dumps(response_data)

    def get_upm_token(self):
        if upm_token_server.verify_token():
            upm_token = upm_token_server.get_redis_token()
            if not upm_token:
                print("token获取失败")
            else:
                return upm_token
        else:
            print("token授权失败")


# 创建服务实例
def get_upm_token_server():
    # 配置参数
    config = {
        "app_id": "autoDeploy",
        "app_secret": "ucmjwlyhdi2k6w5pxvfgvi",
        "login_id": "cdp-xxjob",
        "password": "CDP-xxjob@1234",
        "get_token_url": "https://www.cdp.changan.com.cn/upm/api/appUserLogin",
        "verify_token_url": "https://www.cdp.changan.com.cn/upm/api/user/info",
        "redis_key": "xxjob-userRedisKey",
        "redis_host": "10.64.67.33",
        "redis_db": 5,
        "redis_port": "56379",
        "redis_password": "B2o0N1z!NbELRfZj"
    }

    return UpmTokenServer(**config)
